<?php declare(strict_types=1);
/**
 * Created by IntelliJ IDEA
 * Author: 张伯发
 * Date  : 2019/11/19
 * Time  : 11:34
 */

namespace App\Service\Members;


use App\Dto\Request\Members\MembersLogoutRequestDTO;
use App\Dto\Response\Members\MembersLoginResponseDTO;
use App\Dto\Response\Members\MembersRegisterResponseDTO;
use App\Model\Dao\MembersDao;
use App\Dto\Request\Members\MembersLoginRequestDTO;
use App\Dto\Request\Members\MembersRegisterRequestDTO;
use App\Dto\Response\Members\MembersMessageResponseDTO;
use App\Service\Members\MembersMessageService;
use App\Service\VerifyCodeService;
use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Bean\Annotation\Mapping\Inject;

use Swoft\Bean\Exception\ContainerException;
use \ReflectionException;
use Swoft\Db\Exception\DbException;
use Swoft\Redis\Pool;
use Xiaoproject\Common\Base\BaseService;
use Xiaoproject\Common\Language\L;


/**
 * 用户的登录、注册、登出相关的业务
 * Class MembersService
 * @author 张伯发 2019/11/19 11:34
 * @Bean()
 */
class MembersLoginRegisterLogoutService extends BaseService
{
    /**
     * @Inject()
     * @var MembersDao
     */
    protected $dao;

    /**
     * @Inject()
     * @var VerifyCodeService
     */
    protected $verifyCodeService;

    /**
     * @Inject()
     * @var MembersMessageService
     */
    protected $membersMessageService;

    /**
     * 会员注册
     *
     * @param MembersRegisterRequestDTO $dto
     * @return MembersRegisterResponseDTO
     * @throws ContainerException
     * @throws DbException
     * @throws ReflectionException
     * @author 张伯发 2019/11/19 12:00
     */
    public function register(MembersRegisterRequestDTO $dto) : ?MembersRegisterResponseDTO
    {
        $username = $dto->getUsername();
        // 1. 判断验证码是否正确，通过手机号
        $cacheCode = $this->verifyCodeService->getMembersRegisterCode($username);
        if ($cacheCode !== $dto->getVerifyCode()) {
            $this->setMessage(L::get('members.register_verify_code_error'));
            return null;
        }

        // 2. 判断用户是否已经注册
        $member = $this->dao->findMemberByUsername($username);
        if (!empty($member)) {
            $this->setMessage(L::get('members.register_exists'));
            $this->verifyCodeService->delMembersRegisterCode($username);
            return null;
        }

        // 3. 注册用户
        $membersResult = $this->dao->registerMember($username,$dto->getPassword(), $dto->getNickname(), $dto->getHeadIcon());
        if (empty($membersResult)) {
            $this->setMessage(L::get('members.register_failed'));
            return null;
        }
        // 删除cache verify code
        $this->verifyCodeService->delMembersRegisterCode($username);

        $responseDto = new MembersRegisterResponseDTO();
        $responseDto->setUsername($membersResult->getUsername());
        $responseDto->setNickname($membersResult->getNickname());
        $responseDto->setHeadIcon($membersResult->getHeadIcon());
        $token = $this->membersMessageService->setCacheMembersMessage($membersResult);
        $responseDto->setToken($token);
        return $responseDto;
    }


    /**
     * @param MembersLoginRequestDTO $dto
     * @return MembersLoginResponseDTO
     * @throws DbException
     * @author 张伯发 2019/11/22 11:58
     */
    public function login(MembersLoginRequestDTO $dto) : ?MembersLoginResponseDTO
    {
        $username = $dto->getUsername();
        $password = $dto->getPassword();
        $dbMemberInfo = $this->dao->findMemberByUsername($username);
        if (empty($dbMemberInfo)) {
            $this->setMessage(L::get('members.login_user_not_exists'));
            return null;
        }

        $dbUsername = $dbMemberInfo->getUsername();
        $dbPassword = $dbMemberInfo->getPassword();

        if ($username !== $dbUsername) {
            $this->setMessage(L::get('members.login_user_not_exists'));
            return null;
        }

        if (!password_verify($password, $dbPassword)) {
            $this->setMessage(L::get('members.login_error'));
            return null;
        }

        $responseDto = new MembersLoginResponseDTO();
        $responseDto->setUsername($dbUsername);
        $responseDto->setNickname($dbMemberInfo->getNickname());
        $responseDto->setHeadIcon($dbMemberInfo->getHeadIcon());

        $token = $this->membersMessageService->setCacheMembersMessage($dbMemberInfo);
        $responseDto->setToken($token);
        return $responseDto;
    }

    /**
     *
     * @param MembersLogoutRequestDTO $dto
     * @return bool
     * @author 张伯发 2019/11/23 10:56
     */
    public function logout(MembersLogoutRequestDTO $dto) : bool
    {
        $token = $dto->getToken();
        $result = $this->membersMessageService->delCacheMembersMessage($token);
        if ($result === false) {
            $this->setMessage($this->membersMessageService->getMessage());
            return false;
        }
        return true;
    }
}
